﻿using System;
using System.Text;
using RedBit.OAuthLibrary;

namespace TradeMeSDK
{
    public class TradeMeMyTradeMe
    {
        #region Listing Methods

        public void DownloadAllUnansweredQuestions(Action<BaseEventArgs<Questions>> callback)
        {
            WebHelper.DownloadAndParseProtected(TradeMeConstants.AllUnansweredQuestions, callback);
        }

        public void DownloadUnansweredQuestions(int listingId, Action<BaseEventArgs<Questions>> callback)
        {
            string url = TradeMeConstants.ListingsUrl + listingId + "/questions/unansweredquestions.json";
            WebHelper.DownloadAndParseProtected(url, callback);
        }

        public void PostComment(int listingId, string comment, Action<BaseEventArgs<Question>> callback)
        {
            string url = TradeMeConstants.SecureListingsUrl + listingId + "/addcomment.json";

            string content = string.Format(
                @"<ListingAddComment xmlns=""http://api.trademe.co.nz/v1""><comment>{0}</comment></ListingAddComment>",
                comment
                );
            WebHelper.PostAndParseProtected(url, content, callback);
        }

        public void AnswerQuestion(int listingId, int questionId, string answer, Action<BaseEventArgs<Question>> callback)
        {
            string url = string.Format("/v1/Listings/{0}/questions/{1}/answerquestion.json",
                        listingId, questionId);

            string content = string.Format(
                @"<ListingAnswerQuestion xmlns=""http://api.trademe.co.nz/v1""><answer>{0}</answer></ListingAnswerQuestion>",
                answer
                );
            WebHelper.PostAndParseProtected(url, content, callback);
        }

        public void EmailToSeller(int listingId, string message, bool copyToSelf, Action<BaseEventArgs<TradeMeResult>> callback)
        {
            string url = string.Format("/v1/Listings/{0}/emailseller.json", listingId);

            string content = string.Format(
                @"<EmailRequest xmlns=""http://api.trademe.co.nz/v1""><Message>{0}</Message></EmailRequest>",
                message);
            WebHelper.PostAndParseProtected(url, content, callback);
        }

        public void EmailToFriend(int listingId, string message, bool copySelf, string emailAddress, Action<BaseEventArgs<TradeMeResult>> callback)
        {
            string url = string.Format("/v1/Listings/{0}/emailfriend.json", listingId);

            string content = string.Format(
                @"<EmailFriendRequest xmlns=""http://api.trademe.co.nz/v1""><Message>{0}</Message><EmailTo>{1}</EmailTo></EmailFriendRequest>",
                message, emailAddress);
            WebHelper.PostAndParseProtected(url, content, callback);
        }

        #endregion

        #region Bidding

        public void PlaceBid(BidRequest bidRequest, Action<BaseEventArgs<TradeMeResult>> callback)
        {
            string content = string.Format(@"<BidRequest xmlns=""http://api.trademe.co.nz/v1""><ListingId>{0}</ListingId><Amount>{1}</Amount><AutoBid>{2}</AutoBid><ShippingOption>{3}</ShippingOption></BidRequest>",
                                           bidRequest.ListingId, 
										   bidRequest.Amount,
                                           bidRequest.AutoBid.ToString().ToLower(), 
										   bidRequest.ShippingOption);
            WebHelper.PostAndParseProtected(TradeMeConstants.BidRequest, content, callback);
        }

        public void BuyNow(BuyNowRequest buyNowRequest, Action<BaseEventArgs<TradeMeResult>> callback)
        {
            string content = string.Format(@"<BuyNowRequest xmlns=""http://api.trademe.co.nz/v1""><ListingId>{0}</ListingId><ShippingOption>{1}</ShippingOption></BuyNowRequest>",
                                           buyNowRequest.ListingId, buyNowRequest.ShippingOption);
            WebHelper.PostAndParseProtected(TradeMeConstants.BuyNowRequest, content, callback);
        }


        #endregion


        #region MyTradeMe Methods

        public void MyTradeMeSummary(Action<BaseEventArgs<MyTradeMeSummary>> callback)
        {
            WebHelper.DownloadAndParseProtected(TradeMeConstants.MyTradeMeSummaryUrl, callback);
        }

        private static string CombineCriteria(string url, MyTradeMeCriteria criteria)
        {
            if (criteria == null)
                return url + ".json";

            StringBuilder query = new StringBuilder();
            WebHelper.AddParameter("page", criteria.Page, query);
            WebHelper.AddParameter("rows", criteria.Rows, query);

            string full;
            if (criteria.Criteria == null)
                full = url + ".json";
            else
                full = url + "/" + criteria.Criteria + ".json";

            return full + "?" + query;
        }

        /// <summary>
        /// Possible Criteria
        /// Last45Days	        Returns items sold in the last 45 days.
        /// Last30Days	        Returns items sold in the last 30 days.
        /// Last7Days	        Returns items sold in the last 7 days.
        /// Last3Days	        Returns items sold in the last 3 days.
        /// Last24Hours	        Returns items sold in the last 24 hours.
        /// PaymentInstructionsToSend	Returns items without sent payment instructions.
        /// FeedbackToPlace	    Returns items with pending feedback.
        /// EmailSent	        Returns sold items marked with "Email sent" status.
        /// PaymentReceived	    Returns sold items marked with "Payment received" status.
        /// GoodsShipped	    Returns sold items marked with "Goods shipped" status.
        /// SaleCompleted	    Returns sold items marked with "Sale completed" status.
        /// </summary>
        public void MyTradeMeSoldItems(MyTradeMeCriteria criteria, Action<BaseEventArgs<Listings>> callback)
        {
            string url = CombineCriteria(TradeMeConstants.MyTradeMeSoldItems, criteria);
            WebHelper.DownloadAndParseProtected(url, callback);
        }

        /// <summary>
        /// Possible Criteria
        /// Last45Days	        Returns items sold in the last 45 days.
        /// Last7Days	        Returns items sold in the last 7 days.
        /// Last24Hours	        Returns items sold in the last 24 hours.
        /// ItemsIHaveOffered	Returns items with pending offers.
        /// ItemsICanRelist	    Returns unsold items that can be relisted.
        /// </summary>
        public void MyTradeMeUnsoldItems(MyTradeMeCriteria criteria, Action<BaseEventArgs<Listings>> callback)
        {
            string url = CombineCriteria(TradeMeConstants.MyTradeMeUnsoldItems, criteria);
            WebHelper.DownloadAndParseProtected(url, callback);
        }

        /// <summary>
        /// Possible Criteria
        /// All	                Returns all currently active listings.
        /// ClosingToday        Return only listings that are due to close in 24 hours.
        /// ListingsWithBids    Returns listings with bids.
        /// ReserveMet          Returns listings where the reserve price is met.
        /// ReserveNotMet       Returns listings where the reserve price is not met.
        /// UnansweredQuestions Returns listings with unanswered questions.
        /// </summary>
        public void MyTradeMeSellingItems(MyTradeMeCriteria criteria, Action<BaseEventArgs<Listings>> callback)
        {
            string url = CombineCriteria(TradeMeConstants.MyTradeMeSellingItems, criteria);
            WebHelper.DownloadAndParseProtected(url, callback);
        }

        /// <summary>
        /// Possible Criteria
        /// All	            Returns all items from the Watchlist.
        /// ClosingToday    Returns listings that are closing today.
        /// LeadingBids	    Returns listings where the authenticated user leads the bidding.
        /// ReserveMet	    Returns listings where highest bid is above the Reserve price or the Reserve price equals the Start price (= No reserve).
        /// ReserveNotMet	Returns only listings where the reserve has not been met.
        /// </summary>
        public void MyTradeMeWatchlist(MyTradeMeCriteria criteria, Action<BaseEventArgs<Listings>> callback)
        {
            string url = CombineCriteria(TradeMeConstants.MyTradeMeWatchList, criteria);
            WebHelper.DownloadAndParseProtected(url, callback);
        }

        /// <summary>
        /// Possible Criteria
        /// All	        Return all won items.
        /// Last30Days	Return items won in the last 30 days.
        /// Last7Days	Return items won in the last 7 days.
        /// Last24Hours	Return items won in the last 24 hours.
        /// </summary>
        public void MyTradeMeWonItems(MyTradeMeCriteria criteria, Action<BaseEventArgs<Listings>> callback)
        {
            string url = CombineCriteria(TradeMeConstants.MyTradeMeWon, criteria);
            WebHelper.DownloadAndParseProtected(url, callback);
        }

        /// <summary>
        /// Possible Criteria
        /// All	        Return all lost items.
        /// Last30Days	Return items lost in the last 30 days.
        /// Last7Days	Return items lost in the last 7 days.
        /// Last24Hours	Return items lost in the last 24 hours.
        /// </summary>
        public void MyTradeMeLostItems(MyTradeMeCriteria criteria, Action<BaseEventArgs<Listings>> callback)
        {
            string url = CombineCriteria(TradeMeConstants.MyTradeMeLost, criteria);
            WebHelper.DownloadAndParseProtected(url, callback);
        }

        /// <summary>
        /// Possible Criteria
        /// All	        Return all member ledger records.
        /// Last45Days	Return member ledger records from the last 45 days.
        /// Last28Days	Return member ledger records from the last 28 days.
        /// Last14Days	Return member ledger records from the last 14 days.
        /// Last7Days	Return member ledger records from the last 7 days.
        /// Last24Hours	Return member ledger records from the last 24 hours.
        /// </summary>
        public void MyTradeMeMemberLedger(MyTradeMeCriteria criteria, Action<BaseEventArgs<MemberLedger>> callback)
        {
            string url = CombineCriteria(TradeMeConstants.MyTradeMeMemberLedger, criteria);
            WebHelper.DownloadAndParseProtected(url, callback);
        }

        /// <summary>
        /// Possible Criteria
        /// All	                    Returns all Pay Now ledger records
        /// Sales	                Return only sale payments
        /// PaymentsToMyBankAccount	Return only ledger records with payments to the member's bank account.
        /// Refunds	                Returns only Pay Now refunds.
        /// </summary>
        public void MyTradeMePayNowLedger(MyTradeMeCriteria criteria, Action<BaseEventArgs<PayNowLedger>> callback)
        {
            string url = CombineCriteria(TradeMeConstants.MyTradeMePayNowLedger, criteria);
            WebHelper.DownloadAndParseProtected(url, callback);
        }

        public void MyTradeMeAddToWatchList(int listingId, Action<BaseEventArgs<WatchListResult>> callback)
        {
            string url = TradeMeConstants.MyTradeMeWatchList + "/" + listingId + ".json";
            WebHelper.PostAndParseProtected(url, "", callback);
        }


        #endregion


        #region Member Photos

        public void DownloadMemberPhotos(Action<BaseEventArgs<MemberPhotos>> callback)
        {
            WebHelper.DownloadAndParseProtected(TradeMeConstants.MemberPhotos, callback);
        }

        public void RemoveMemberPhoto(int photoId, Action<BaseEventArgs<Member>> callback)
        {
            string url = TradeMeConstants.RemoveMemberPhoto + photoId + "/Remove.json";
            WebHelper.DownloadAndParseProtected(url, callback);
        }

        #endregion       
    }
}